package com.epam.giorgadze.task3.parsers;

import com.epam.giorgadze.task3.entity.AirCompany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * User: Luka
 * Date: 14.03.14
 * Time: 20:45
 */
public class ParserManager {
    private static final Logger log = LoggerFactory.getLogger(ParserManager.class);
    public static List<AirCompany> DOMManager(String xmlName, String xsdName) {

        List<AirCompany> airCompanyList = null;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setValidating(false);
            dbf.setNamespaceAware(true);
            SchemaFactory schemaFactory = SchemaFactory
                    .newInstance("http://www.w3.org/2001/XMLSchema");
            dbf.setSchema(schemaFactory
                    .newSchema(new Source[]{new StreamSource(xsdName)}));
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse(xmlName);
            Element root = document.getDocumentElement();
            airCompanyList = new ArrayList<AirCompany>();
            airCompanyList.add(AirCompanyDOMParser.listBuilder(root));
        } catch (ParserConfigurationException e) {
            log.error("Parser Configuration Exception");
        } catch (SAXException e) {
            log.error("SAX Exception");
        } catch (IOException e) {
            log.error("IO Exception");
        }
        log.info("XML document parse with DOM parser");
        return airCompanyList;
    }


    public static List<AirCompany> SAXManager(String xmlName, String xsdName) {
        List<AirCompany> airCompanyList = new ArrayList<AirCompany>();
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            SchemaFactory schemaFactory = SchemaFactory
                    .newInstance("http://www.w3.org/2001/XMLSchema");
            factory.setSchema(schemaFactory.newSchema(new Source[]{new StreamSource(xsdName)}));
            SAXParser parser = factory.newSAXParser();
            XMLReader reader = parser.getXMLReader();
            AirCompanySAXParser airCompanySAXParser = new AirCompanySAXParser();
            reader.setContentHandler(airCompanySAXParser);
            reader.parse(xmlName);
            airCompanyList.add(airCompanySAXParser.getAirCompany());
        } catch (SAXException e) {
            log.error("SAX Exception");
        } catch (ParserConfigurationException e) {
            log.error("Parser Configuration Exception");
        } catch (IOException e) {
            log.error("IO Exception");
        }
        log.info("XML document parsed with SAX parser");
        return airCompanyList;
    }

    public static List<AirCompany> StAXMANAGER(String xmlName) throws FileNotFoundException {
        List<AirCompany> airCompanyList = new ArrayList<AirCompany>();
        AirCompanyStAXParser parser = new AirCompanyStAXParser();
        InputStream inputStream = new FileInputStream(xmlName);
        parser.parse(inputStream);
        airCompanyList.add(parser.getAircompany());
        log.info("XML document parsed with StAX parser");
        return airCompanyList;
    }

    public static void JAXBManager(String xmlName, AirCompany airCompany){
        JAXBContext context = null;
        try {
            context = JAXBContext.newInstance(AirCompany.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.marshal(airCompany, new FileOutputStream(xmlName));
        } catch (JAXBException e) {
            log.error("JAXB exception");
        } catch (FileNotFoundException e) {
            log.error("File not found exception");
        }
    }
}
